Template Literale (Template Strings)
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.
Template Literale sind Literale, die mit Backtick-Zeichen (`
) begrenzt werden und mehrzeilige Zeichenketten, String-Interpolationen mit eingebetteten Ausdrücken und spezielle Konstrukte namens tagged templates ermöglichen.
Template Literale werden manchmal informell Template Strings genannt, da sie am häufigsten zur String-Interpolation verwendet werden (um Zeichenketten durch Ersetzen von Platzhaltern zu erstellen). Ein tagged Template Literal muss jedoch nicht in einer Zeichenkette resultieren; es kann mit einer benutzerdefinierten Tag-Funktion verwendet werden, um beliebige Operationen auf den verschiedenen Teilen des Template-Literals auszuführen.
Syntax
`string text`
`string text line 1
string text line 2`
`string text ${expression} string text`
tagFunction`string text ${expression} string text`
Parameter
string text
-
Der Zeichenketten-Text, der Teil des Template-Literals wird. Fast alle Zeichen sind buchstäblich erlaubt, einschließlich Zeilenumbrüche und andere Leerzeichen. Ungültige Escape-Sequenzen führen jedoch zu einem Syntaxfehler, es sei denn, es wird eine Tag-Funktion verwendet.
expression
-
Ein Ausdruck, der an der aktuellen Position eingefügt wird, dessen Wert in eine Zeichenkette umgewandelt oder an
tagFunction
übergeben wird. tagFunction
-
Falls angegeben, wird sie mit dem Template-Strings-Array und den Substitutionsausdrücken aufgerufen, und der Rückgabewert wird der Wert des Template-Literals. Siehe tagged templates.
Beschreibung
Template Literale werden durch Backtick-Zeichen (`
) anstelle von doppelten oder einfachen Anführungszeichen eingeschlossen.
Zusätzlich zu normalen Zeichenketten können Template Literale auch andere Teile enthalten, die Platzhalter genannt werden. Diese sind eingebettete Ausdrücke, die durch ein Dollarzeichen und geschweifte Klammern begrenzt sind: ${expression}
. Die Zeichenketten und Platzhalter werden an eine Funktion übergeben - entweder eine Standardfunktion oder eine von Ihnen bereitgestellte Funktion. Die Standardfunktion (wenn Sie keine eigene bereitstellen) führt nur eine String-Interpolation durch, um die Platzhalter zu ersetzen und die Teile dann in einer einzelnen Zeichenkette zu verketten.
Um eine eigene Funktion bereitzustellen, stellen Sie dem Template-Literal einen Funktionsnamen voran; das Ergebnis wird als tagged Template bezeichnet. In diesem Fall wird das Template-Literal an Ihre Tag-Funktion übergeben, wo Sie dann beliebige Operationen auf den verschiedenen Teilen des Template-Literals ausführen können.
Um einen Backtick in einem Template-Literal zu escapen, setzen Sie einen Backslash (\
) vor den Backtick.
`\`` === "`"; // true
Dollarzeichen können ebenfalls escaped werden, um die Interpolation zu verhindern.
`\${1}` === "${1}"; // true
Mehrzeilige Zeichenketten
Alle in der Quelle eingefügten Newline-Zeichen sind Teil des Template-Literals.
Mit normalen Zeichenketten müssten Sie die folgende Syntax verwenden, um mehrzeilige Zeichenketten zu erhalten:
console.log("string text line 1\nstring text line 2");
// "string text line 1
// string text line 2"
Mit Template-Literalen können Sie dasselbe damit tun:
console.log(`string text line 1
string text line 2`);
// "string text line 1
// string text line 2"
Wie bei normalen Zeichenketten-Literalen können Sie eine einzeilige Zeichenkette über mehrere Zeilen schreiben, um die Lesbarkeit des Quellcodes zu verbessern, indem Sie den Zeilenumbruch mit einem Backslash (\
) escapen:
console.log(`string text line 1 \
string text line 2`);
// "string text line 1 string text line 2"
String-Interpolation
Ohne Template-Literale, wenn Sie Ausgaben aus Ausdrücken mit Zeichenketten kombinieren möchten, würden Sie sie verkettet mit dem Additionsoperator +
:
const a = 5;
const b = 10;
console.log("Fifteen is " + (a + b) + " and\nnot " + (2 * a + b) + ".");
// "Fifteen is 15 and
// not 20."
Das kann schwer lesbar sein – besonders wenn Sie mehrere Ausdrücke haben.
Mit Template-Literalen können Sie den Verkettungsoperator vermeiden – und die Lesbarkeit Ihres Codes verbessern – indem Sie Platzhalter in der Form von ${expression}
verwenden, um Ersetzungen für eingebettete Ausdrücke vorzunehmen:
const a = 5;
const b = 10;
console.log(`Fifteen is ${a + b} and
not ${2 * a + b}.`);
// "Fifteen is 15 and
// not 20."
Beachten Sie, dass es einen leichten Unterschied zwischen den beiden Syntaxen gibt. Template-Literale zwingen ihre Ausdrücke direkt zur Zeichenkette, während die Addition ihre Operanden zuerst zu Primitiven zwingt. Weitere Informationen finden Sie auf der Referenzseite für den +
Operator.
Verschachtelte Templates
In bestimmten Fällen ist die Verschachtelung eines Templates der einfachste (und vielleicht lesbarere) Weg, um konfigurierbare Zeichenketten zu haben. Innerhalb eines mit Backticks begrenzten Templates ist es einfach, innere Backticks zuzulassen, indem Sie sie innerhalb eines ${expression}
-Platzhalters im Template verwenden.
Ohne Template-Literale könnten Sie, wenn Sie einen bestimmten Wert basierend auf einer bestimmten Bedingung zurückgeben möchten, etwas wie das Folgende tun:
let classes = "header";
classes += isLargeScreen()
? ""
: item.isCollapsed
? " icon-expander"
: " icon-collapser";
Mit einem Template-Literal, aber ohne Verschachtelung, könnten Sie dies tun:
const classes = `header ${
isLargeScreen() ? "" : item.isCollapsed ? "icon-expander" : "icon-collapser"
}`;
Mit der Verschachtelung von Template-Literalen können Sie dies tun:
const classes = `header ${
isLargeScreen() ? "" : `icon-${item.isCollapsed ? "expander" : "collapser"}`
}`;
Tagged Templates
Eine fortgeschrittenere Form von Template-Literalen sind tagged templates.
Tags ermöglichen es Ihnen, Template-Literale mit einer Funktion zu parsen. Das erste Argument einer Tag-Funktion enthält ein Array von String-Werten. Die verbleibenden Argumente beziehen sich auf die Ausdrücke.
Die Tag-Funktion kann dann beliebige Operationen auf diesen Argumenten durchführen und die manipulierte Zeichenkette zurückgeben. (Alternativ kann sie auch etwas völlig anderes zurückgeben, wie in einem der folgenden Beispiele beschrieben.)
Der Name der für das Tag verwendeten Funktion kann beliebig sein.
const person = "Mike";
const age = 28;
function myTag(strings, personExp, ageExp) {
const str0 = strings[0]; // "That "
const str1 = strings[1]; // " is a "
const str2 = strings[2]; // "."
const ageStr = ageExp < 100 ? "youngster" : "centenarian";
// We can even return a string built using a template literal
return `${str0}${personExp}${str1}${ageStr}${str2}`;
}
const output = myTag`That ${person} is a ${age}.`;
console.log(output);
// That Mike is a youngster.
Das Tag muss kein einfacher Bezeichner sein. Sie können jeden Ausdruck mit einem Präzedenz größer als 16 verwenden, was Eigenschaftszugriffe, Funktionsaufrufe, new expression oder sogar ein weiteres tagged Template Literal umfasst.
console.log`Hello`; // [ 'Hello' ]
console.log.bind(1, 2)`Hello`; // 2 [ 'Hello' ]
new Function("console.log(arguments)")`Hello`; // [Arguments] { '0': [ 'Hello' ] }
function recursive(strings, ...values) {
console.log(strings, values);
return recursive;
}
recursive`Hello``World`;
// [ 'Hello' ] []
// [ 'World' ] []
Obwohl technisch durch die Syntax erlaubt, generieren untagged Template Literale Zeichenketten und lösen einen TypeError
bei Verkettung aus.
console.log(`Hello``World`); // TypeError: "Hello" is not a function
Die einzige Ausnahme ist optionales Chaining, das einen Syntaxfehler auslösen wird.
console.log?.`Hello`; // SyntaxError: Invalid tagged template on optional chain
console?.log`Hello`; // SyntaxError: Invalid tagged template on optional chain
Beachten Sie, dass diese beiden Ausdrücke weiterhin analysierbar sind. Das bedeutet, dass sie nicht der automatischen Semikolon-Einfügung unterliegen würden, die nur Semikolons einfügt, um Code zu korrigieren, der ansonsten nicht analysierbar ist.
// Still a syntax error
const a = console?.log
`Hello`
Tag-Funktionen müssen nicht einmal eine Zeichenkette zurückgeben!
function template(strings, ...keys) {
return (...values) => {
const dict = values[values.length - 1] || {};
const result = [strings[0]];
keys.forEach((key, i) => {
const value = Number.isInteger(key) ? values[key] : dict[key];
result.push(value, strings[i + 1]);
});
return result.join("");
};
}
const t1Closure = template`${0}${1}${0}!`;
// const t1Closure = template(["","","","!"],0,1,0);
t1Closure("Y", "A"); // "YAY!"
const t2Closure = template`${0} ${"foo"}!`;
// const t2Closure = template([""," ","!"],0,"foo");
t2Closure("Hello", { foo: "World" }); // "Hello World!"
const t3Closure = template`I'm ${"name"}. I'm almost ${"age"} years old.`;
// const t3Closure = template(["I'm ", ". I'm almost ", " years old."], "name", "age");
t3Closure("foo", { name: "MDN", age: 30 }); // "I'm MDN. I'm almost 30 years old."
t3Closure({ name: "MDN", age: 30 }); // "I'm MDN. I'm almost 30 years old."
Das erste Argument, das von der Tag-Funktion empfangen wird, ist ein Array von Zeichenfolgen. Für jedes Template-Literal ist seine Länge gleich der Anzahl der Substitutionen (Vorkommen von ${…}
) plus eins und daher immer nicht leer.
Für jeden speziellen tagged Template Literal Ausdruck wird die Tag-Funktion immer mit demselben Literal-Array aufgerufen, egal wie oft das Literal ausgewertet wird.
const callHistory = [];
function tag(strings, ...values) {
callHistory.push(strings);
// Return a freshly made object
return {};
}
function evaluateLiteral() {
return tag`Hello, ${"world"}!`;
}
console.log(evaluateLiteral() === evaluateLiteral()); // false; each time `tag` is called, it returns a new object
console.log(callHistory[0] === callHistory[1]); // true; all evaluations of the same tagged literal would pass in the same strings array
Dies ermöglicht es dem Tag, das Ergebnis basierend auf der Identität seines ersten Arguments zwischenzuspeichern. Um die Stabilität des Array-Wertes weiter zu gewährleisten, sind das erste Argument und seine raw
Eigenschaft beide gefroren, sodass Sie sie in keiner Weise ändern können.
Rohe Zeichenfolgen
Die spezielle raw
-Eigenschaft, die beim ersten Argument der Tag-Funktion verfügbar ist, ermöglicht es Ihnen, auf die rohen Zeichenfolgen zuzugreifen, wie sie eingegeben wurden, ohne die Escape-Sequenzen zu verarbeiten.
function tag(strings) {
console.log(strings.raw[0]);
}
tag`string text line 1 \n string text line 2`;
// Logs "string text line 1 \n string text line 2",
// including the two characters '\' and 'n'
Zusätzlich existiert die Methode String.raw()
, um rohe Zeichenfolgen zu erstellen, genau wie die Standard-Template-Funktion und Zeichenfolgenverkettung es tun würden.
const str = String.raw`Hi\n${2 + 3}!`;
// "Hi\\n5!"
str.length;
// 6
Array.from(str).join(",");
// "H,i,\\,n,5,!"
String.raw
fungiert wie ein "Identitäts"-Tag, wenn das Literal keine Escape-Sequenzen enthält. Falls Sie ein tatsächliches Identitäts-Tag wünschen, das immer funktioniert, als ob das Literal ungetaggt wäre, können Sie eine benutzerdefinierte Funktion erstellen, die das "gekochte" (d.h. Escape-Sequenzen sind verarbeitet) Literal-Array an String.raw
weitergibt und vorgibt, dass sie rohe Zeichenfolgen sind.
const identity = (strings, ...values) =>
String.raw({ raw: strings }, ...values);
console.log(identity`Hi\n${2 + 3}!`);
// Hi
// 5!
Dies ist nützlich für viele Tools, die Literale mit einem bestimmten Namen speziell behandeln.
const html = (strings, ...values) => String.raw({ raw: strings }, ...values);
// Some formatters will format this literal's content as HTML
const doc = html`<!doctype html>
<html lang="en-US">
<head>
<title>Hello</title>
</head>
<body>
<h1>Hello world!</h1>
</body>
</html>`;
Tagged Templates und Escape-Sequenzen
In normalen Template-Literalen sind die Escape-Sequenzen in Zeichenfolgen-Literalen alle erlaubt. Jede andere nicht wohlgeformte Escape-Sequenz ist ein Syntaxfehler. Dies umfasst:
\
gefolgt von einer Dezimalziffer außer0
oder\0
gefolgt von einer Dezimalziffer; beispielsweise\9
und\07
(was eine veraltete Syntax ist)\x
gefolgt von weniger als zwei Hexadezimalziffern (einschließlich keiner); beispielsweise\xz
\u
nicht gefolgt von{
und gefolgt von weniger als vier Hexadezimalziffern (einschließlich keiner); beispielsweise\uz
\u{}
umschließt einen ungültigen Unicode-Codepunkt — es enthält ein nicht-hexadezimales Zeichen, oder sein Wert ist größer als10FFFF
; beispielsweise\u{110000}
und\u{z}
Hinweis: \
gefolgt von anderen Zeichen, obwohl sie nutzlos sein könnten, da nichts escaped ist, sind keine Syntaxfehler.
Dies ist jedoch problematisch für tagged Templates, die neben dem "gekochten" Literal auch Zugang zu den rohen Literalen haben (Escape-Sequenzen bleiben unverändert).
Tagged Templates ermöglichen das Einbetten von beliebigen Zeichenketteninhalten, bei denen Escape-Sequenzen einer anderen Syntax folgen können. Betrachten Sie ein Beispiel, in dem wir LaTeX Quelltext über String.raw
in JavaScript einbetten. Wir möchten immer noch LaTeX-Makros verwenden können, die mit u
oder x
beginnen, ohne die Einschränkungen der JavaScript-Syntax zu beachten. Daher wird die Syntax-Einschränkung für wohlgeformte Escape-Sequenzen von tagged Templates entfernt. Das folgende Beispiel nutzt MathJax, um LaTeX in einem Element zu rendern:
const node = document.getElementById("formula");
MathJax.typesetClear([node]);
// Throws in older ECMAScript versions (ES2016 and earlier)
// SyntaxError: malformed Unicode character escape sequence
node.textContent = String.raw`$\underline{u}$`;
MathJax.typesetPromise([node]);
Illegale Escape-Sequenzen müssen jedoch dennoch in der "gekochten" Darstellung dargestellt werden. Sie werden als undefined
Element im "gekochten" Array angezeigt:
function log(str) {
console.log("Cooked:", str[0]);
console.log("Raw:", str.raw[0]);
}
log`\unicode`;
// Cooked: undefined
// Raw: \unicode
Beachten Sie, dass die Einschränkung der Escape-Sequenz nur von tagged Templates, aber nicht von untagged Template-Literalen entfernt wird:
const bad = `bad escape sequence: \unicode`;
Spezifikationen
Specification |
---|
ECMAScript® 2026 Language Specification # sec-template-literals |
Browser-Kompatibilität
Siehe auch
- Zahlen und Zeichenketten Leitfaden
String
String.raw()
- Lexikalische Grammatik
- ES6 in Depth: Template strings auf hacks.mozilla.org (2015)